use serde::{Deserialize, Serialize};
use std::sync::LazyLock;

pub const CONFIG_FILE_NAME: &str = "config.toml";

pub static CONFIG: LazyLock<Config> = LazyLock::new(|| {
    let config_result = parse();
    match config_result {
        Ok(config) => config,
        Err(e) => panic!("parse config toml error =>{:?} ", e),
    }
});

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
    pub server: ServerConfig,
    pub database: DatabaseConfig,
    pub log: LogConfig,
    pub client: ClientConfig,
    pub wechat_config: WechatConfig,
    pub wcferry: WcferryConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WcferryConfig {
    pub path: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerConfig {
    pub tcp: String,
    pub http: String,
    pub ws: String,
    pub udp: String,
    pub token: TokenConfig,
    pub file: FileConfig,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TokenConfig {
    pub expire: i64,
    pub secret: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileConfig {
    pub path: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseConfig {
    pub sqlite: SqliteConfig,
    pub mysql: MysqlConfig,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SqliteConfig {
    pub url: String,
    pub username: String,
    pub password: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MysqlConfig {
    pub url: String,
    pub username: String,
    pub password: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LogConfig {
    pub path: String,
    pub name: String,
    pub env: Vec<EnvConfig>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnvConfig {
    pub name: String,
    pub level: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClientConfig {
    pub tcp: String,
}

/// 微信sdk配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatConfig {
    pub app_id: String, // 应用id
    pub secret: String, // 密钥
    // pub token: String,          // token,在接口配置时填写的token,用于sigine验证
    // pub msg_type: MessageFormat,    // 消息格式
    // pub encrypt_mode: EncryptMode   // 加密方式
    pub mch_id: String,      //商户id
    pub private_key: String, //商户证书私钥
    pub certificate: String, //商户证书路径
    pub secret_key: String,  //API 秘钥
    pub serial_no: String,
    pub v3_key: String,
    pub notify_url: String,
}

pub fn parse() -> anyhow::Result<Config> {
    let settings = config::Config::builder()
        .add_source(config::File::with_name(CONFIG_FILE_NAME)) // 可选的指定文件名
        .build()?;

    let app_config = settings.try_deserialize::<Config>()?;

    //let app_config = toml::from_str::<Config>(&contents)?;
    Ok(app_config)
}
